﻿// RankingSejmowy 1.0 - Polish parliment statistics for the masses.
// Copyright (C) 2010 Jarosław Dubrownik
//  
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//  
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//  
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
using System.Collections.Generic;
using System.Text.RegularExpressions;
using RankingSejmowy.Common.Exceptions;
using RankingSejmowy.Common.Extensions;
using RankingSejmowy.Model;
using RankingSejmowy.Model.Import;

namespace RankingSejmowy.BLL.Import.Parser.PageParsers
{
    internal class VotingParser : IVotingParser
    {
        private const string VOTING_TITLE_PATTERN =
            @"G.OSOWANIE.+?(?'voting'\d+).+?(?'meeting'\d+).+?(?'date'\d{2}-\d{2}-\d{4}).+?(?'time'\d{2}:\d{2})";

        private const string VOTING_SUBJECT_PATTERN = @"class=""naz""><B>(?'subject'.+?)</B>";

        private const string VOTING_DESCRIPTION_PATTERN = @" class=""nrm"">.+?>(?'desc'.+?)<";

        #region IVotingParser Members

        public void Parse(IEnumerable<SiteMapPage> votingPages, Meeting meeting, IParserFactory parserFactory)
        {
            foreach (var votingPage in votingPages)
            {
                ParseVoting(votingPage, meeting, parserFactory);
            }
        }

        #endregion

        private static void ParseVotingDescription(Voting voting, string content)
        {
            var match = content.Match(VOTING_DESCRIPTION_PATTERN, RegexOptions.Singleline);
            if (!match.Success)
            {
                throw new ParseException("voting description");
            }

            voting.Description = match.Groups["desc"].Value;
        }

        private static void ParseVotingSubject(Voting voting, string content)
        {
            var match = content.Match(VOTING_SUBJECT_PATTERN, RegexOptions.Singleline);
            if (!match.Success)
            {
                throw new ParseException("voting subject");
            }

            voting.Subject = match.Groups["subject"].Value;
        }

        private static void ParseVotingTitle(Voting voting, string content)
        {
            var match = content.Match(VOTING_TITLE_PATTERN, RegexOptions.Singleline);
            if (!match.Success)
            {
                throw new ParseException("voting title");
            }

            voting.Date =
                string.Format("{0} {1}", match.Groups["date"].Value, match.Groups["time"].Value).ConvertToDateTime(
                    "dd-MM-yyyy HH:mm");
            voting.VotingNum = match.Groups["voting"].Value.ConvertTo<int>();
        }

        private void ParseVoting(SiteMapPage votingPage, Meeting meeting, IParserFactory parserFactory)
        {
            var content = votingPage.DownloadedPage.GetContent();
            var voting = new Voting();
            try
            {
                ParseVotingTitle(voting, content);
                ParseVotingSubject(voting, content);
                ParseVotingDescription(voting, content);
            }
            catch (ParseException e)
            {
                throw new ParseException(string.Format("voting page ({0})", votingPage.Uri), e);
            }

            meeting.AddVoting(voting);
            var parser = parserFactory.CreatePartyVotingParser();
            parser.Parse(votingPage.SubPages, voting);
        }
    }
}